package com.jjwxc.jwjskandriod.readActivity.view;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.widget.Toast;

import androidx.core.content.ContextCompat;

import com.jjwxc.jwjskandriod.R;
import com.jjwxc.jwjskandriod.framework.utils.FFLogUtil;
import com.jjwxc.jwjskandriod.framework.utils.PreUtils;
import com.jjwxc.jwjskandriod.framework.utils.StUtils;
import com.jjwxc.jwjskandriod.readActivity.ReadActivity;
import com.jjwxc.jwjskandriod.readActivity.bean.BookRecordBean;
import com.jjwxc.jwjskandriod.readActivity.bean.CollBookBean;
import com.jjwxc.jwjskandriod.readActivity.local.BookRepository;
import com.jjwxc.jwjskandriod.readActivity.local.ReadSettingManager;
import com.jjwxc.jwjskandriod.readActivity.utils.BitmapUtil;
import com.jjwxc.jwjskandriod.readActivity.utils.Constant;
import com.jjwxc.jwjskandriod.readActivity.utils.FileUtil;
import com.jjwxc.jwjskandriod.readActivity.utils.RxUtils;
import com.jjwxc.jwjskandriod.readActivity.utils.ScreenUtils;
import com.jjwxc.jwjskandriod.readActivity.utils.StringUtils;
import com.jjwxc.jwjskandriod.readActivity.utils.ToastUtils;

import java.io.BufferedReader;
import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.SingleObserver;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.disposables.Disposable;


public abstract class PageLoader {
    private static final String TAG = "PageLoader";

    // 当前页面的状态
    public static final int STATUS_LOADING = 1;         // 正在加载
    public static final int STATUS_FINISH = 2;          // 加载完成
    public static final int STATUS_ERROR = 3;           // 加载错误 (一般是网络加载情况)
    public static final int STATUS_EMPTY = 4;           // 空数据
    public static final int STATUS_PARING = 5;          // 正在解析 (装载本地数据)
    public static final int STATUS_PARSE_ERROR = 6;     // 本地文件解析错误(暂未被使用)
    public static final int STATUS_CATEGORY_EMPTY = 7;  // 获取到的目录为空
    // 默认的显示参数配置
    private static final int DEFAULT_MARGIN_HEIGHT = 28;
    private static final int DEFAULT_MARGIN_WIDTH = 15;
    private static final int DEFAULT_TIP_SIZE = 12;
    private static final int EXTRA_TITLE_SIZE = 4;

    // 当前章节列表
    protected List<TxtChapter> mChapterList;
    // 书本对象
    protected CollBookBean mCollBook;
    // 监听器
    protected OnPageChangeListener mPageChangeListener;

    private Context mContext;
    // 页面显示类
    private PageView mPageView;
    // 当前显示的页
    private TxtPage mCurPage;
    // 上一章的页面列表缓存
    private List<TxtPage> mPrePageList;
    // 当前章节的页面列表
    private List<TxtPage> mCurPageList;
    // 下一章的页面列表缓存
    private List<TxtPage> mNextPageList;

    // 绘制电池的画笔
    private Paint mBatteryPaint;
    // 绘制提示的画笔
    private Paint mTipPaint;
    // 绘制标题的画笔
    private Paint mTitlePaint;
    // 绘制背景颜色的画笔(用来擦除需要重绘的部分)
    private Paint mBgPaint;
    // 绘制小说内容的画笔
    private TextPaint mTextPaint;
    // 阅读器的配置选项
    private ReadSettingManager mSettingManager;
    // 被遮盖的页，或者认为被取消显示的页
    private TxtPage mCancelPage;
    // 存储阅读记录类
    public BookRecordBean mBookRecord;

    private Disposable mPreLoadDisp;

    /*****************params**************************/
    // 当前的状态
    protected int mStatus = STATUS_LOADING;
    // 判断章节列表是否加载完成
    protected boolean isChapterListPrepare;

    // 是否打开过章节
    public boolean isChapterOpen;
    private boolean isFirstOpen = true;
    private boolean userIsVip = false;
    private boolean isClose;
    // 页面的翻页效果模式
    private PageMode mPageMode;
    // 加载器的颜色主题
    private PageStyle mPageStyle;
    //当前是否是夜间模式
    private boolean isNightMode;
    //书籍绘制区域的宽高
    private int mVisibleWidth;
    private int mVisibleHeight;
    //应用的宽高
    private int mDisplayWidth;
    private int mDisplayHeight;

    public int mSafeInsetTop;

    //间距
    private int mMarginWidth;
    private int mMarginHeight;
    //字体的颜色
    private int mTextColor;
    //标题的大小
    private int mTitleSize;
    //字体的大小
    private int mTextSize;
    //字体的路径
    private String mTypefacePath;
    //行间距
    private int mTextInterval;
    //标题的行间距
    private int mTitleInterval;
    //段落距离(基于行间距的额外距离)
    private int mTextPara;
    private int mTitlePara;
    //电池的百分比
    private int mBatteryLevel;
    //当前页面的背景
    private int mBgColor;

    // 当前章
    protected int mCurChapterPos = 0;
    //上一章的记录
    private int mLastChapterPos = 0;

    /*****************************init params*******************************/
    public PageLoader(PageView pageView, CollBookBean collBook) {
        mPageView = pageView;
        mContext = pageView.getContext();
        mCollBook = collBook;
        mChapterList = new ArrayList<>(1);

        // 初始化数据
        initData();
        // 初始化画笔
        initPaint();
        // 初始化PageView
        initPageView();
        // 初始化书籍
        prepareBook();
    }

    private void initData() {
        // 获取配置管理器
        mSettingManager = ReadSettingManager.getInstance();
        // 获取配置参数
        mPageMode = mSettingManager.getPageMode();
        mPageStyle = mSettingManager.getPageStyle();
        // 初始化参数
        mMarginWidth = ScreenUtils.dpToPx(DEFAULT_MARGIN_WIDTH);
        mMarginHeight = ScreenUtils.dpToPx(DEFAULT_MARGIN_HEIGHT);
        // 配置文字有关的参数
        setUpTextParams(mSettingManager.getTextSize(), mSettingManager.getTextInterval(), mSettingManager.getTypefacePath());
    }

    /**
     * 作用：设置与文字相关的参数
     *
     * @param textSize
     */
    private void setUpTextParams(int textSize, int textInterval, String typefacePath) {
        // 文字大小
        mTextSize = textSize;
        //字体
        mTypefacePath = typefacePath;
        mTitleSize = mTextSize + ScreenUtils.spToPx(EXTRA_TITLE_SIZE);
        // 行间距(大小为字体的一半)
        mTextInterval = mTextSize / 2 * textInterval;
        mTitleInterval = mTitleSize / 2 * textInterval;
        // 段落间距(大小为字体的高度)
        mTextPara = mTextSize;
        mTitlePara = mTitleSize;
    }

    private void initPaint() {
        // 绘制提示的画笔
        mTipPaint = new Paint();
        mTipPaint.setColor(mTextColor);
        mTipPaint.setTextAlign(Paint.Align.LEFT); // 绘制的起始点
        mTipPaint.setTextSize(ScreenUtils.spToPx(DEFAULT_TIP_SIZE)); // Tip默认的字体大小
        mTipPaint.setAntiAlias(true);
        mTipPaint.setSubpixelText(true);

        // 绘制页面内容的画笔
        mTextPaint = new TextPaint();
        mTextPaint.setColor(mTextColor);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setAntiAlias(true);

        // 绘制标题的画笔
        mTitlePaint = new TextPaint();
        mTitlePaint.setColor(mTextColor);
        mTitlePaint.setTextSize(mTitleSize);
        mTitlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mTitlePaint.setTypeface(Typeface.DEFAULT_BOLD);
        mTitlePaint.setAntiAlias(true);

        // 绘制背景的画笔
        mBgPaint = new Paint();
        mBgPaint.setColor(mBgColor);

        // 绘制电池的画笔
        mBatteryPaint = new Paint();
        mBatteryPaint.setAntiAlias(true);
        mBatteryPaint.setDither(true);
        //设置字体
        if (!StringUtils.isEmpty(mTypefacePath) && FileUtil.checkFileExist(mTypefacePath)) {
            mTextPaint.setTypeface(Typeface.createFromFile(new File(mTypefacePath)));
            mTitlePaint.setTypeface(Typeface.createFromFile(new File(mTypefacePath)));
        } else {
            mTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
            mTitlePaint.setTypeface(Typeface.DEFAULT_BOLD);
        }
        // 初始化页面样式
        setNightMode(mSettingManager.isNightMode());
    }

    private void initPageView() {
        //配置参数
        mPageView.setPageMode(mPageMode);
        mPageView.setBgColor(mBgColor);
    }

    /****************************** public method***************************/
    /**
     * 跳转到上一章
     *
     * @return
     */
    public boolean skipPreChapter() {
        if (!hasPrevChapter()) {
            return false;
        }

        // 载入上一章。
        if (parsePrevChapter()) {
            mCurPage = getCurPage(0);
        } else {
            mCurPage = new TxtPage();
        }
        mPageView.drawCurPage(false);
        return true;
    }

    /**
     * 跳转到下一章
     *
     * @return
     */
    public boolean skipNextChapter() {
        if (!hasNextChapter()) {
            return false;
        }

        //判断是否达到章节的终止点
        if (parseNextChapter()) {
            mCurPage = getCurPage(0);
        } else {
            mCurPage = new TxtPage();
        }
        mPageView.drawCurPage(false);
        return true;
    }

    /**
     * 根据字数跳转到章节的第几页
     *
     * @param words:从 0 开始。
     */
    public void skipWordToPage(int words) {
        int pos = wordToPage(words);
        skipToPage(pos);
    }

    /**
     * 根据字数，计算出所在页
     *
     * @param words
     * @return
     */
    public int wordToPage(int words) {

        int line;
        int lineWord;
        int pageWord;
        int pos = 0;
        if (words > 0 && mCurPage != null && mCurPage.lines != null && mCurPage.lines.size() > 0) {
            //获取当前页面所有字的行
            List<String> mList = new ArrayList<>();
            mList.addAll(mCurPage.getLines());
            line = mCurPage.lines.size();
            //获取最长的一行多少个字
            Collections.sort(mList);
            lineWord = mList.get(0).length();
            //一页有多少行
            pageWord = line * lineWord;
            //字数到第几页
            pos = words / pageWord;
            //页码从1开始的,所以+1
            pos = pos + 1;
        } else if (words == -1) {
            pos = -1;
        }
        return pos;
    }

    /**
     * 跳转到指定章节
     *
     * @param pos:从 0 开始。
     */
    public void skipToChapter(int pos) {
        // 设置参数
        mCurChapterPos = pos;

        // 将上一章的缓存设置为null
        mPrePageList = null;
        // 如果当前下一章缓存正在执行，则取消
        if (mPreLoadDisp != null) {
            mPreLoadDisp.dispose();
        }
        // 将下一章缓存设置为null
        mNextPageList = null;

        // 打开指定章节
        openChapter();
    }

    /**
     * 跳转到指定的页
     *
     * @param pos
     */
    public boolean skipToPage(int pos) {
        if (!isChapterListPrepare) {
            return false;
        }
        mCurPage = getCurPage(pos);
        mPageView.drawCurPage(false);
        return true;
    }

    /**
     * 翻到上一页
     *
     * @return
     */
    public boolean skipToPrePage() {
        return mPageView.autoPrevPage();
    }

    /**
     * 翻到下一页
     *
     * @return
     */
    public boolean skipToNextPage() {
        return mPageView.autoNextPage();
    }

    /**
     * 更新时间
     */
    public void updateTime() {
        if (!mPageView.isRunning()) {
            mPageView.drawCurPage(true);
        }
    }

    /**
     * 更新电量
     *
     * @param level
     */
    public void updateBattery(int level) {
        mBatteryLevel = level;

        if (!mPageView.isRunning()) {
            mPageView.drawCurPage(true);
        }
    }

    /**
     * 设置提示的文字大小
     *
     * @param textSize:单位为 px。
     */
    public void setTipTextSize(int textSize) {
        mTipPaint.setTextSize(textSize);

        // 如果屏幕大小加载完成
        mPageView.drawCurPage(false);
    }

    /**
     * 设置文字相关参数
     *
     * @param textSize
     */
    public void setTextSize(int textSize, int textInterval, String typefacePath) {
        // 设置文字相关参数
        setUpTextParams(textSize, textInterval, typefacePath);

        if (!StringUtils.isEmpty(typefacePath) && FileUtil.checkFileExist(typefacePath)) {
            mTextPaint.setTypeface(Typeface.createFromFile(new File(typefacePath)));
            mTitlePaint.setTypeface(Typeface.createFromFile(new File(typefacePath)));
        } else {
            mTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
            mTitlePaint.setTypeface(Typeface.DEFAULT_BOLD);
        }

        // 设置画笔的字体大小
        mTextPaint.setTextSize(mTextSize);
        // 设置标题的字体大小
        mTitlePaint.setTextSize(mTitleSize);
        // 存储文字大小
        mSettingManager.setTextSize(mTextSize);
        // 取消缓存
        mPrePageList = null;
        mNextPageList = null;

        // 如果当前已经显示数据
        if (isChapterListPrepare && mStatus == STATUS_FINISH) {
            // 重新计算当前页面
            dealLoadPageList(mCurChapterPos);

            // 防止在最后一页，通过修改字体，以至于页面数减少导致崩溃的问题
            if (mCurPage.position >= mCurPageList.size()) {
                mCurPage.position = mCurPageList.size() - 1;
            }

            // 重新获取指定页面
            mCurPage = mCurPageList.get(mCurPage.position);
        }

        mPageView.drawCurPage(false);
    }

    /**
     * 设置夜间模式
     *
     * @param nightMode
     */
    public void setNightMode(boolean nightMode) {
        mSettingManager.setNightMode(nightMode);
        isNightMode = nightMode;

        if (isNightMode) {
            mBatteryPaint.setColor(Color.WHITE);
            setPageStyle(PageStyle.NIGHT);
        } else {
            mBatteryPaint.setColor(Color.parseColor("#222222"));
            setPageStyle(mPageStyle);
        }
    }

    /**
     * 设置页面样式
     *
     * @param pageStyle:页面样式
     */
    public void setPageStyle(PageStyle pageStyle) {
        if (pageStyle != PageStyle.NIGHT) {
            mPageStyle = pageStyle;
            mSettingManager.setPageStyle(pageStyle);
        }

        if (isNightMode && pageStyle != PageStyle.NIGHT) {
            return;
        }

        // 设置当前颜色样式
        mTextColor = ContextCompat.getColor(mContext, pageStyle.getFontColor());
        mBgColor = ContextCompat.getColor(mContext, pageStyle.getBgColor());

        mTipPaint.setColor(mTextColor);
        mTitlePaint.setColor(mTextColor);
        mTextPaint.setColor(mTextColor);
        mBgPaint.setColor(mBgColor);

        mPageView.drawCurPage(false);
    }

    /**
     * 翻页动画
     *
     * @param pageMode:翻页模式
     * @see PageMode
     */
    public void setPageMode(PageMode pageMode) {
        mPageMode = pageMode;

        mPageView.setPageMode(mPageMode);
        mSettingManager.setPageMode(mPageMode);

        // 重新绘制当前页
        mPageView.drawCurPage(false);
    }

    /**
     * 设置内容与屏幕的间距
     *
     * @param marginWidth  :单位为 px
     * @param marginHeight :单位为 px
     */
    public void setMargin(int marginWidth, int marginHeight) {
        mMarginWidth = marginWidth;
        mMarginHeight = marginHeight;

        // 如果是滑动动画，则需要重新创建了
        if (mPageMode == PageMode.SCROLL) {
            mPageView.setPageMode(PageMode.SCROLL);
        }

        mPageView.drawCurPage(false);
    }

    /**
     * 设置页面切换监听
     *
     * @param listener
     */
    public void setOnPageChangeListener(OnPageChangeListener listener) {
        mPageChangeListener = listener;

        // 如果目录加载完之后才设置监听器，那么会默认回调
        if (isChapterListPrepare) {
            mPageChangeListener.onCategoryFinish(mChapterList);
        }
    }

    /**
     * 获取当前页的状态
     *
     * @return
     */
    public int getPageStatus() {
        return mStatus;
    }

    /**
     * 获取书籍信息
     *
     * @return
     */
    public CollBookBean getCollBook() {
        return mCollBook;
    }

    /**
     * 获取章节目录。
     *
     * @return
     */
    public List<TxtChapter> getChapterCategory() {
        return mChapterList;
    }


    /**
     * 获取当前页的页码
     *
     * @return
     */
    public int getPagePos() {
        return mCurPage.position;
    }

    /**
     * 获取当前页内容
     *
     * @return
     */
    public String getPageContent() {
        String content = "";
        if (mCurPage.lines != null) {
            for (int i = 1; i < mCurPage.lines.size(); i++) {
                content = content + mCurPage.lines.get(i);
            }

        }
        return content;
    }

    /**
     * 获取当前章节的章节位置
     *
     * @return
     */
    public int getChapterPos() {
        return mCurChapterPos;
    }

    public TxtChapter getTxtChapter() {
        if (null == getChapterCategory() || getChapterCategory().isEmpty()) {
            return null;
        }

        return getChapterCategory().get(mCurChapterPos);
    }

    /**
     * 获取距离屏幕的高度
     *
     * @return
     */
    public int getMarginHeight() {
        return mMarginHeight;
    }

    /**
     * 获取当前页面进度比例
     *
     * @return
     */
    public int getChapterScale() {
        return mCurChapterPos * 100 / mChapterList.size();

    }

    /**
     * 获取当前页面字数位置
     *
     * @return
     */
    public int getWordNum() {
        int line;
        int word;
        if (mCurPage.lines != null) {
            line = mCurPage.lines.size();
            List<String> mList = new ArrayList<>();
            mList.addAll(mCurPage.getLines());
            //获取最长的一行多少个字
            Collections.sort(mList);
            word = mList.get(0).length();
        } else {
            line = 0;
            word = 1;
        }
        //页码*一页行数*一行文字=总共多少个字
        return mCurPage.position * line * word;
    }

    /**
     * 保存阅读记录
     */
    public void saveRecord() {

        if (mChapterList.isEmpty() || mCollBook == null) {
            return;
        }

        mBookRecord.setBookId(mCollBook.get_id());
        mBookRecord.setChapter(mCurChapterPos);

        if (mCurPage != null) {
            mBookRecord.setPagePos(mCurPage.position);
        } else {
            mBookRecord.setPagePos(0);
        }

        //存储到数据库
        BookRepository.getInstance()
                .saveBookRecord(mBookRecord);
    }

    /**
     * 初始化书籍
     */
    private void prepareBook() {
        mBookRecord = BookRepository.getInstance()
                .getBookRecord(mCollBook.get_id());

        if (mBookRecord == null) {
            mBookRecord = new BookRecordBean();
            mCurChapterPos = mCollBook.getChaptersCount();
        } else {
            mCurChapterPos = mBookRecord.getChapter();
        }
        mLastChapterPos = mCurChapterPos;

    }

    /**
     * 打开指定章节
     */
    public void openChapter() {
        isFirstOpen = false;

        if (!mPageView.isPrepare()) {
            return;
        }

        // 如果章节目录没有准备好
        if (!isChapterListPrepare) {
            mStatus = STATUS_LOADING;
            mPageView.drawCurPage(false);
            return;
        }

        // 如果获取到的章节目录为空
        if (mChapterList.isEmpty()) {
            mStatus = STATUS_CATEGORY_EMPTY;
            mPageView.drawCurPage(false);
            return;
        }

        if (parseCurChapter()) {
            // 如果章节从未打开
            if (!isChapterOpen) {
                int position = 0;
                if (mCurChapterPos == mBookRecord.getChapter()) {
                    position = mBookRecord.getPagePos();
                }
                // 防止记录页的页号，大于当前最大页号
                if (position >= mCurPageList.size()) {
                    position = mCurPageList.size() - 1;
                }
                mCurPage = getCurPage(position);
                mCancelPage = mCurPage;
                // 切换状态
                isChapterOpen = true;
            } else {
                mCurPage = getCurPage(0);
            }
        } else {
            mCurPage = new TxtPage();
        }

        mPageView.drawCurPage(false);

    }

    public void chapterError() {
        //加载错误
        mStatus = STATUS_ERROR;
        mPageView.drawCurPage(false);
    }

    /**
     * 关闭书本
     */
    public void closeBook() {
        isChapterListPrepare = false;
        isClose = true;

        if (mPreLoadDisp != null) {
            mPreLoadDisp.dispose();
        }

        clearList(mChapterList);
        clearList(mCurPageList);
        clearList(mNextPageList);

        mChapterList = null;
        mCurPageList = null;
        mNextPageList = null;
        mPageView = null;
        mCurPage = null;
    }

    private void clearList(List list) {
        if (list != null) {
            list.clear();
        }
    }

    public boolean isClose() {
        return isClose;
    }

    public boolean isChapterOpen() {
        return isChapterOpen;
    }

    public void setChapterOpen(boolean chapterOpen) {
        isChapterOpen = chapterOpen;
    }

    /**
     * 加载页面列表
     *
     * @param chapterPos:章节序号
     * @return
     */
    private List<TxtPage> loadPageList(int chapterPos) throws Exception {
        if (!mChapterList.isEmpty() && chapterPos >= mChapterList.size()) {
            chapterPos = mChapterList.size() - 1;
        }

        // 获取章节
        TxtChapter chapter = mChapterList.get(chapterPos);
        // 判断章节是否存在
        if (!hasChapterData(chapter)) {
            return null;
        }
        // 获取章节的文本流
        BufferedReader reader = getChapterReader(chapter);
//        List<TxtPage> chapters = loadPages(chapter, reader);
//        ...

        // test by zhangjian
        String line;
        ArrayList<String> lines = new ArrayList<>();
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        List<TxtPage> chapters = loadPages(chapter, lines);

        // 根据加载章节页面数量判断是否手动添加权限
        if (chapters != null && chapters.size() > 1) {
            chapter.setHasAuth(true);
            mChapterList.set(chapterPos, chapter);
        }

        return chapters;
    }

    /*******************************abstract method***************************************/

    /**
     * 刷新章节列表
     */
    public abstract void refreshChapterList(boolean openChapter);

    /**
     * 获取章节的文本流
     *
     * @param chapter
     * @return
     */
    protected abstract BufferedReader getChapterReader(TxtChapter chapter) throws Exception;

    /**
     * 章节数据是否存在
     *
     * @return
     */
    protected abstract boolean hasChapterData(TxtChapter chapter);

    /***********************************default method***********************************************/

    void drawPage(Bitmap bitmap, boolean isUpdate) {
        if (!isNightMode && mSettingManager.getPageStyleBgPos() < 3) {
            isUpdate = false;
        }
        if (mPageView != null) {
            drawBackground(mPageView.getBgBitmap(), isUpdate);
            if (!isUpdate) {
                drawContent(bitmap);
            }
            //更新绘制
            mPageView.invalidate();
        } else {
            Toast.makeText(mContext, "数据绘制界面错误,请重试", Toast.LENGTH_LONG).show();
            ((ReadActivity) mContext).finish();
        }

    }

    private void drawBackground(Bitmap bitmap, boolean isUpdate) {
        if (bitmap == null) {
            Toast.makeText(mContext, "数据绘制界面错误,请重试", Toast.LENGTH_LONG).show();
            ((ReadActivity) mContext).finish();
            return;
        }
        Canvas canvas = new Canvas(bitmap);
        int tipMarginHeight = ScreenUtils.dpToPx(3);
        if (!isUpdate) {
            /****绘制背景***绘制图片还是颜色*/
            if (!isNightMode && mSettingManager.getPageStyleBgPos() < 3) {
                //获取图片bitmap
                bitmap = BitmapUtil.getBgBitmap(mSettingManager.getPageStyleBgPos(),
                        mDisplayWidth, mDisplayHeight);
                canvas.drawBitmap(bitmap, 0, 0, null);
            } else {
                canvas.drawColor(mBgColor);
            }
            if (mChapterList != null && !mChapterList.isEmpty()) {
                /*****初始化标题的参数********/
                //需要注意的是:绘制text的y的起始点是text的基准线的位置，而不是从text的头部的位置
                float tipTop = tipMarginHeight - mTipPaint.getFontMetrics().top + mSafeInsetTop;
                //根据状态不一样，数据不一样
                if (mStatus != STATUS_FINISH) {
                    if (isChapterListPrepare && mChapterList.size() > mCurChapterPos) {
                        canvas.drawText(mChapterList.get(mCurChapterPos).getTitle()
                                , mMarginWidth, tipTop, mTipPaint);
                    }
                } else {
                    //左上角书本的名称
                    String mTitle = "< " + mCollBook.getTitle();
                    // 获取文本宽度
                    float bookTitleWidth = mTipPaint.measureText(mTitle);
                    float percent = (mDisplayWidth / 2 - mMarginWidth) / bookTitleWidth;
                    int end = mTitle.length();
                    if (percent < 1) {
                        end = (int) (end * percent) - 1;
                        mTitle = mTitle.substring(0, end) + "...";
                    }
                    canvas.drawText(mTitle, mMarginWidth, tipTop, mTipPaint);

                    // 设置Title区域
                    Rect titleFrame = new Rect(mMarginWidth, 0, (int) (mMarginWidth + bookTitleWidth), (int)  (mTipPaint.descent() - mTipPaint.ascent() + tipTop));
                    setTitleRect(titleFrame);


                    // 右上角 章节名称
                    String pageTitle = mCurPage.title;
                    // 获取文本宽度
                    float pageTitleWidth = mTipPaint.measureText(pageTitle);
                    float pagePercent = (mDisplayWidth / 2 - mMarginWidth) / pageTitleWidth;
                    int pageEnd = pageTitle.length();
                    if (pagePercent < 1) {
                        pageEnd = (int) (pageEnd * pagePercent);
                        pageTitle = pageTitle.substring(0, pageEnd) + "...";
                    }

                    float offX = mMarginWidth + mVisibleWidth - mTipPaint.measureText(pageTitle);
                    canvas.drawText(pageTitle, offX, tipTop, mTipPaint);
                }
            }
        } else {
            //擦除区域颜色
            if (!isNightMode && mSettingManager.getPageStyleBgPos() < 3) {
                mBgPaint.setColor(Color.TRANSPARENT);
            } else {
                mBgPaint.setColor(mBgColor);
            }

            // zhangjian 解决右下脚白色块
            float tipHeight = mTipPaint.getTextSize();
            canvas.drawRect(mDisplayWidth / 2, mDisplayHeight - tipHeight - ScreenUtils.dpToPx(3), mDisplayWidth, mDisplayHeight, mBgPaint);
        }

        // 只有finish的时候采用页码
        if (mCurPageList != null && !mCurPageList.isEmpty()
                && mChapterList != null && !mChapterList.isEmpty()
                && mStatus == STATUS_FINISH) {
            /******绘制章节进度********/
            // 获取章节进度百分比
            String percentage = StUtils.percentage(mCurChapterPos + 1, mChapterList.size());
            float x = mDisplayWidth - mMarginWidth - mTipPaint.measureText(percentage) - ScreenUtils.dpToPx(4);
            // 底部的字显示的位置Y
            float y = mDisplayHeight - mTipPaint.getFontMetrics().bottom - tipMarginHeight;

            canvas.drawText(percentage, x, y, mTipPaint);

            /******绘制页码********/
            // 底部的字显示的位置X
            String percent = (mCurPage.position + 1) + "/" + mCurPageList.size();
            float x1 = x - mTipPaint.measureText(percent) - ScreenUtils.dpToPx(10);

            canvas.drawText(percent, x1, y, mTipPaint);
        }

        tipMarginHeight = ScreenUtils.dpToPx(8);

        /******繪制電池********/
        int visibleRight = mDisplayWidth - mMarginWidth;
        int visibleBottom = mDisplayHeight - tipMarginHeight;

        //外框的製作
        int border = 1;
        int outFrameHeight = (int) mTipPaint.getTextSize();

        int outFrameLeft = mMarginWidth;
        int outFrameWidth = outFrameLeft + (int) mTipPaint.measureText("xxx");
        int outFrameTop = visibleBottom - outFrameHeight;
        int outFrameBottom = visibleBottom - ScreenUtils.dpToPx(2);
        Rect outFrame = new Rect(outFrameLeft, outFrameTop, outFrameWidth, outFrameBottom);

        mBatteryPaint.setStyle(Paint.Style.STROKE);
        mBatteryPaint.setStrokeWidth(border);
        canvas.drawRect(outFrame, mBatteryPaint);

        //內框的製作
        int innerMargin = 1;

        float innerWidth = (outFrame.width() - innerMargin * 2 - border) * (mBatteryLevel / 100.0f);
        RectF innerFrame = new RectF(outFrameLeft + border + innerMargin, outFrameTop + border + innerMargin,
                outFrameLeft + border + innerMargin + innerWidth, outFrameBottom - border - innerMargin);

        mBatteryPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(innerFrame, mBatteryPaint);

        //電極的製作
        int polarHeight = ScreenUtils.dpToPx(6);
        int polarWidth = ScreenUtils.dpToPx(2);
        int polarLeft = outFrameWidth + polarWidth;
        int polarRight = polarLeft + polarWidth;
        int polarTop = visibleBottom - (outFrameHeight + polarHeight) / 2;
        Rect polar = new Rect(polarLeft, polarTop, polarRight,
                polarTop + polarHeight - ScreenUtils.dpToPx(2));

        mBatteryPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(polar, mBatteryPaint);

        /******绘制当前时间********/
        //底部的字显示的位置Y
        float y = mDisplayHeight - mTipPaint.getFontMetrics().bottom - tipMarginHeight;
        String time = StringUtils.dateConvert(System.currentTimeMillis(), Constant.FORMAT_TIME);
        float x = outFrameLeft + mTipPaint.measureText(time) + ScreenUtils.dpToPx(4);

        // 时间更新时，需要擦除该区域颜色，然后再重新绘制，否则会造成文字重叠
        //擦除区域颜色
        if (!isNightMode && mSettingManager.getPageStyleBgPos() < 3) {
            mBgPaint.setColor(Color.RED);
        } else {
            mBgPaint.setColor(mBgColor);
        }
        Rect timeFrame = new Rect((int) x, (int) (y + mTipPaint.ascent() - mTipPaint.descent()), (int) (x + mTipPaint.measureText(time)), (int) y);
        mBgPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(timeFrame, mBgPaint);

        canvas.drawText(time, x, y, mTipPaint);
    }

    // 获取 Title 出现区域
    private Rect rect = new Rect();

    public Rect getTitleRect() {
        return rect;
    }

    public void setTitleRect(Rect rect) {
        this.rect = rect;
    }

    private void drawContent(Bitmap bitmap) {
        Canvas canvas = new Canvas(bitmap);

        if (mPageMode == PageMode.SCROLL) {
            //绘制图片还是颜色
            if (!isNightMode && mSettingManager.getPageStyleBgPos() < 3) {
                canvas.drawColor(Color.TRANSPARENT);
            } else {
                canvas.drawColor(mBgColor);
            }
        }
        /******绘制内容****/

        if (mStatus != STATUS_FINISH) {
            //绘制字体
            String tip = "";
            switch (mStatus) {
                case STATUS_LOADING:
                    tip = "正在拼命加载中...";
                    break;
                case STATUS_ERROR:
                    tip = "加载失败(点击边缘重试)";
                    break;
                case STATUS_EMPTY:
                    tip = "~更多精彩情节，购买后即可阅读~";
                    break;
                case STATUS_PARING:
                    tip = "正在排版请等待...";
                    break;
                case STATUS_PARSE_ERROR:
                    tip = "文件解析错误";
                    break;
                case STATUS_CATEGORY_EMPTY:
                    tip = "加载目录失败";
                    break;
            }

            //将提示语句放到正中间
            drawCenter(tip, canvas);
        } else {
            float top;

            if (mPageMode == PageMode.SCROLL) {
                top = -mTextPaint.getFontMetrics().top + mSafeInsetTop;
            } else {
                top = mMarginHeight - mTextPaint.getFontMetrics().top + mSafeInsetTop;
            }

            //设置总距离
            int interval = mTextInterval + (int) mTextPaint.getTextSize();
            int para = mTextPara + (int) mTextPaint.getTextSize();
            int titleInterval = mTitleInterval + (int) mTitlePaint.getTextSize();
            int titlePara = mTitleInterval + (int) mTextPaint.getTextSize();
            // String str = null;

            //对标题进行绘制
            for (int i = 0; i < mCurPage.titleLines; ++i) {
                String str = mCurPage.getLines().get(i);
                FFLogUtil.i("PageLoader", "mCurPage.titleLines --->: " + str);

                //设置顶部间距
                if (i == 0) {
                    top += mTitlePara;
                }

                //计算文字显示的起始点
                int start = (int) (mDisplayWidth - mTitlePaint.measureText(str)) / 2;
                //进行绘制
                // canvas.drawText(str, start, top, mTitlePaint);
                mCurPage.lines.get(i).drawText(canvas, mTitlePaint, start, top, mDisplayWidth);

                //设置尾部间距
                if (i == mCurPage.titleLines - 1) {
                    top += titlePara;
                } else {
                    //行间距
                    top += titleInterval;
                }
            }
            if (mCurPage.titleLines > 0) {
                top += mTitlePara;
            }

            //对内容进行绘制
            for (int i = mCurPage.titleLines; i < mCurPage.lines.size(); ++i) {
                FFLogUtil.i("PageLoader", "mCurPage.lines --->: " + mCurPage.lines.get(i).lineString());

                // str = mCurPage.lines.get(i);
                // canvas.drawText(str, mMarginWidth, top, mTextPaint);
                mCurPage.lines.get(i).drawText(canvas, mTextPaint, mMarginWidth, top, mDisplayWidth);
                if (mCurPage.lines.get(i).isEnd()) {
                    top += para;
                } else {
                    top += interval;
                }
            }

            if (null == mChapterList || mCurChapterPos < 0 || mCurChapterPos > mChapterList.size() - 1) {
                return;
            }

            if (!mChapterList.get(mCurChapterPos).isHasAuth() && 1 == mCurPage.lines.size()) {
                String tip = "~更多精彩情节，购买后即可阅读~";
                //将提示语句放到正中间
                Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
                float textHeight = fontMetrics.top - fontMetrics.bottom;
                float textWidth = mTextPaint.measureText(tip);
                float pivotX = (mDisplayWidth - textWidth) / 2;
                float pivotY = (mDisplayHeight - textHeight) / 3;
                canvas.drawText(tip, pivotX, pivotY, mTextPaint);
            }
        }
    }

    /**
     * 中心文字绘制
     */
    private void drawCenter(String tip, Canvas canvas) {
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float textHeight = fontMetrics.top - fontMetrics.bottom;
        float textWidth = mTextPaint.measureText(tip);
        float pivotX = (mDisplayWidth - textWidth) / 2;
        float pivotY = (mDisplayHeight - textHeight) / 2;
        canvas.drawText(tip, pivotX, pivotY, mTextPaint);
    }

    void prepareDisplay(int w, int h) {
        // 获取PageView的宽高
        mDisplayWidth = w;
        mDisplayHeight = h;

        // 获取内容显示位置的大小
        mVisibleWidth = mDisplayWidth - mMarginWidth * 2;
        mVisibleHeight = mDisplayHeight - mMarginHeight * 2 - mSafeInsetTop;

        // 重置 PageMode
        mPageView.setPageMode(mPageMode);

        if (!isChapterOpen) {
            // 展示加载界面
            mPageView.drawCurPage(false);
            // 如果在 display 之前调用过 openChapter 肯定是无法打开的。
            // 所以需要通过 display 再重新调用一次。
            if (!isFirstOpen) {
                // 打开书籍
                openChapter();
            }
        } else {
            // 如果章节已显示，那么就重新计算页面
            if (mStatus == STATUS_FINISH) {
                dealLoadPageList(mCurChapterPos);
                // 重新设置文章指针的位置
                mCurPage = getCurPage(mCurPage.position);
            }
            mPageView.drawCurPage(false);
        }
    }

    /**
     * 翻阅上一页
     *
     * @return
     */
    boolean prev() {
        // 以下情况禁止翻页
        if (!canTurnPage()) {
            return false;
        }

        if (mStatus == STATUS_FINISH) {
            // 先查看是否存在上一页
            TxtPage prevPage = getPrevPage();
            if (prevPage != null) {
                mCancelPage = mCurPage;
                mCurPage = prevPage;
                mPageView.drawNextPage();
                return true;
            }
        }

        if (!hasPrevChapter()) {
            return false;
        }

        mCancelPage = mCurPage;
        if (parsePrevChapter()) {
            mCurPage = getPrevLastPage();
        } else {
            mCurPage = new TxtPage();
        }
        mPageView.drawNextPage();
        return true;
    }

    /**
     * 解析上一章数据
     *
     * @return:数据是否解析成功
     */
    boolean parsePrevChapter() {
        // 加载上一章数据
        int prevChapter = mCurChapterPos - 1;

        mLastChapterPos = mCurChapterPos;
        mCurChapterPos = prevChapter;

        // 当前章缓存为下一章
        mNextPageList = mCurPageList;

        // 判断是否具有上一章缓存
        if (mPrePageList != null) {
            mCurPageList = mPrePageList;
            mPrePageList = null;

            // 回调
            chapterChangeCallback();
        } else {
            dealLoadPageList(prevChapter);
        }
        return mCurPageList != null ? true : false;
    }

    private boolean hasPrevChapter() {
        //判断是否上一章节为空
        if (mCurChapterPos - 1 < 0) {
            return false;
        }
        return true;
    }

    /**
     * 翻到下一页
     *
     * @return:是否允许翻页
     */
    boolean next() {
        // 以下情况禁止翻页
        if (!canTurnPage()) {
            return false;
        }
        if (mStatus == STATUS_EMPTY) {
            return false;
        }
        if (mStatus == STATUS_FINISH) {
            // 先查看是否存在下一页
            TxtPage nextPage = getNextPage();
            if (nextPage != null) {
                mCancelPage = mCurPage;
                mCurPage = nextPage;
                mPageView.drawNextPage();
                return true;
            }
        }

        if (!hasNextChapter()) {
            if (mCurChapterPos + 1 == mChapterList.size()) {
                ToastUtils.showToastCenter(mContext, "已经到最后一章了");
            }
            return false;
        }

        mCancelPage = mCurPage;
        // 解析下一章数据
        if (parseNextChapter()) {
            mCurPage = mCurPageList.get(0);
        } else {
            mCurPage = new TxtPage();
        }
        mPageView.drawNextPage();
        return true;
    }

    private boolean hasNextChapter() {
        // 判断是否到达目录最后一章
        if (mCurChapterPos + 1 >= mChapterList.size()) {
            return false;
        }
        return true;
    }

    boolean parseCurChapter() {
        // 解析数据
        dealLoadPageList(mCurChapterPos);
        // 预加载下一页面
        preLoadNextChapter();
        return mCurPageList != null ? true : false;
    }

    /**
     * 解析下一章数据
     *
     * @return:返回解析成功还是失败
     */
    boolean parseNextChapter() {
        int nextChapter = mCurChapterPos + 1;

        mLastChapterPos = mCurChapterPos;
        mCurChapterPos = nextChapter;

        // 将当前章的页面列表，作为上一章缓存
        mPrePageList = mCurPageList;

        // 是否下一章数据已经预加载了
        if (mNextPageList != null) {
            mCurPageList = mNextPageList;
            mNextPageList = null;
            // 回调
            chapterChangeCallback();
        } else {
            // 处理页面解析
            dealLoadPageList(nextChapter);
        }
        // 预加载下一页面
        preLoadNextChapter();
        return mCurPageList != null ? true : false;
    }

    private void dealLoadPageList(int chapterPos) {
        try {
            mCurPageList = loadPageList(chapterPos);
            if (mCurPageList != null && mCurPageList.size() > 0) {
                if (mCurPageList.isEmpty()) {
                    mStatus = STATUS_EMPTY;

                    // 添加一个空数据
                    TxtPage page = new TxtPage();
                    page.lines = new ArrayList<>(1);
                    mCurPageList.add(page);

                } else {
                    mStatus = STATUS_FINISH;
                }
            } else {
                mStatus = STATUS_LOADING;
            }
        } catch (Exception e) {
            e.printStackTrace();

            mCurPageList = null;
            mStatus = STATUS_ERROR;
        }

        // 回调
        chapterChangeCallback();
    }

    private void chapterChangeCallback() {
        //翻页的时候查询权限，发送广播通知权限
        if (loadBookAuth) {
            sendsBroadcast();
        }
        if (mPageChangeListener != null) {
            mPageChangeListener.onChapterChange(mCurChapterPos);
            mPageChangeListener.onPageCountChange(mChapterList != null ? mChapterList.size() : 0);
        }
    }

    /**
     * 记载书籍能否刷新权限
     */
    boolean loadBookAuth = false;


    /**
     * 记载书籍能否刷新权限
     */
    public boolean setLoadBookAuth(boolean loadAuth) {
        loadBookAuth = loadAuth;
        return loadBookAuth;
    }

    public void sendsBroadcast() {
        Intent intent = new Intent();

        if (mCurChapterPos < 0 || null == mChapterList || mCurChapterPos > mChapterList.size() - 1) {
            return;
        }
        TxtChapter txtChapter = mChapterList.get(mCurChapterPos);

        if (!txtChapter.isHasAuth() && PreUtils.getBoolean("tourist", false)) {
            intent.setAction(ReadActivity.BOOK_TOURIST);
            mContext.sendBroadcast(intent);
        } else if (!txtChapter.isHasAuth() && txtChapter.isVip() && userIsVip && !txtChapter.isMonthSubscribe()) { //书是vip用户是vip 其他不是
            intent.setAction(ReadActivity.BOOK_VIP);
            mContext.sendBroadcast(intent);
            // 以下情况禁止翻页
//            mStatus = STATUS_EMPTY;
        } else if (!txtChapter.isHasAuth() && !txtChapter.isVip() && txtChapter.isMonthSubscribe()) {//包月 其他不是
            intent.setAction(ReadActivity.BOOK_MONTH);
            mContext.sendBroadcast(intent);
            // 以下情况禁止翻页
//            mStatus = STATUS_EMPTY;
        } else if (!txtChapter.isHasAuth() && txtChapter.isVip() && !userIsVip && !txtChapter.isMonthSubscribe()) {//用户不是vip,书是vip
            intent.setAction(ReadActivity.BOOK_NO);
            mContext.sendBroadcast(intent);
            // 以下情况禁止翻页
//            mStatus = STATUS_EMPTY;
        } else {
//            mStatus = STATUS_FINISH;
            intent.setAction(ReadActivity.BOOK_AUTH);
            mContext.sendBroadcast(intent);
        }
    }

    // 预加载下一章
    private void preLoadNextChapter() {
        int nextChapter = mCurChapterPos + 1;

        // 如果不存在下一章，且下一章没有数据，则不进行加载。
        if (!hasNextChapter()
                || !hasChapterData(mChapterList.get(nextChapter))) {
            return;
        }

        //如果之前正在加载则取消
        if (mPreLoadDisp != null) {
            mPreLoadDisp.dispose();
        }

        //调用异步进行预加载加载
        Single.create(new SingleOnSubscribe<List<TxtPage>>() {
                    @Override
                    public void subscribe(SingleEmitter<List<TxtPage>> e) throws Exception {
                        e.onSuccess(loadPageList(nextChapter));
                    }
                }).compose(RxUtils::toSimpleSingle)
                .subscribe(new SingleObserver<List<TxtPage>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        mPreLoadDisp = d;
                    }

                    @Override
                    public void onSuccess(List<TxtPage> pages) {
                        mNextPageList = pages;
                    }

                    @Override
                    public void onError(Throwable e) {
                        //无视错误
                    }
                });
    }

    // 取消翻页
    void pageCancel() {
        if (mCurPage.position == 0 && mCurChapterPos > mLastChapterPos) { // 加载到下一章取消了
            if (mPrePageList != null) {
                cancelNextChapter();
            } else {
                if (parsePrevChapter()) {
                    mCurPage = getPrevLastPage();
                } else {
                    mCurPage = new TxtPage();
                }
            }
        } else if (mCurPageList == null
                || (mCurPage.position == mCurPageList.size() - 1
                && mCurChapterPos < mLastChapterPos)) {  // 加载上一章取消了

            if (mNextPageList != null) {
                cancelPreChapter();
            } else {
                if (parseNextChapter()) {
                    mCurPage = mCurPageList.get(0);
                } else {
                    mCurPage = new TxtPage();
                }
            }
        } else {
            // 假设加载到下一页，又取消了。那么需要重新装载。
            mCurPage = mCancelPage;
        }
    }

    private void cancelNextChapter() {
        int temp = mLastChapterPos;
        mLastChapterPos = mCurChapterPos;
        mCurChapterPos = temp;

        mNextPageList = mCurPageList;
        mCurPageList = mPrePageList;
        mPrePageList = null;

        chapterChangeCallback();

        mCurPage = getPrevLastPage();
        mCancelPage = null;
    }

    private void cancelPreChapter() {
        // 重置位置点
        int temp = mLastChapterPos;
        mLastChapterPos = mCurChapterPos;
        mCurChapterPos = temp;
        // 重置页面列表
        mPrePageList = mCurPageList;
        mCurPageList = mNextPageList;
        mNextPageList = null;

        chapterChangeCallback();

        mCurPage = getCurPage(0);
        mCancelPage = null;
    }

    /**************************************private method********************************************/
    /**
     * 将章节数据，解析成页面列表
     *
     * @param chapter：章节信息
     * @param br：章节的文本流
     * @return
     */
//    private List<TxtPage> loadPages(TxtChapter chapter, BufferedReader br) {
//        //生成的页面
//        List<TxtPage> pages = new ArrayList<>();
//        //使用流的方式加载
//        List<String> lines = new ArrayList<>();
//        int rHeight = mVisibleHeight;
//        int titleLinesCount = 0;
//        boolean showTitle = true; // 是否展示标题
//        String paragraph = chapter.getTitle();//默认展示标题
//        try {
//            while (showTitle || (paragraph = br.readLine()) != null) {
//                paragraph = paragraph;
//                // 重置段落
//                if (!showTitle) {
//                    paragraph = paragraph.replaceAll("\\s", "");
//                    // 如果只有换行符，那么就不执行
//                    if (paragraph.equals("")) continue;
//                    paragraph = StringUtils.halfToFull("  " + paragraph + "\n");
//                } else {
//                    //设置 title 的顶部间距
//                    rHeight -= mTitlePara;
//                }
//                int wordCount = 0;
//                String subStr = null;
//                while (paragraph.length() > 0) {
//                    //当前空间，是否容得下一行文字
//                    if (showTitle) {
//                        rHeight -= mTitlePaint.getTextSize();
//                    } else {
//                        rHeight -= mTextPaint.getTextSize();
//                    }
//                    // 一页已经填充满了，创建 TextPage
//                    if (rHeight <= 0) {
//                        // 创建Page
//                        TxtPage page = new TxtPage();
//                        page.position = pages.size();
//                        page.title = chapter.getTitle();
//                        page.lines = new ArrayList<>(lines);
//                        page.titleLines = titleLinesCount;
//                        pages.add(page);
//                        // 重置Lines
//                        lines.clear();
//                        rHeight = mVisibleHeight;
//                        titleLinesCount = 0;
//
//                        continue;
//                    }
//
//                    //测量一行占用的字节数
//                    if (showTitle) {
//                        wordCount = mTitlePaint.breakText(paragraph,
//                                true, mVisibleWidth, null);
//                    } else {
//                        wordCount = mTextPaint.breakText(paragraph,
//                                true, mVisibleWidth, null);
//                    }
//
//                    subStr = paragraph.substring(0, wordCount);
//                    if (!subStr.equals("\n")) {
//                        //将一行字节，存储到lines中
//                        lines.add(subStr);
//
//                        //设置段落间距
//                        if (showTitle) {
//                            titleLinesCount += 1;
//                            rHeight -= mTitleInterval;
//                        } else {
//                            rHeight -= mTextInterval;
//                        }
//                    }
//                    //裁剪
//                    paragraph = paragraph.substring(wordCount);
//                }
//
//                //增加段落的间距
//                if (!showTitle && lines.size() != 0) {
//                    rHeight = rHeight - mTextPara + mTextInterval;
//                }
//
//                if (showTitle) {
//                    rHeight = rHeight - mTitlePara + mTitleInterval;
//                    showTitle = false;
//                }
//            }
//
//            if (lines.size() != 0) {
//                //创建Page
//                TxtPage page = new TxtPage();
//                page.position = pages.size();
//                page.title = chapter.getTitle();
//                page.lines = new ArrayList<>(lines);
//                page.titleLines = titleLinesCount;
//                pages.add(page);
//                //重置Lines
//                lines.clear();
//            }
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            IOUtils.close(br);
//        }
//
//        return pages;
//    }


    public final static char[] zhSymbols = "！，。？”".toCharArray();

    private boolean isSymbol(char ch) {
        return ch == zhSymbols[0]
                || ch == zhSymbols[1]
                || ch == zhSymbols[2]
                || ch == zhSymbols[3]
                || ch == zhSymbols[4];
    }

    /***
     * 将文字分割
     * @param paint
     * @param text
     * @param maxWidth
     * @return
     */
    private TxtLine[] cutText(Paint paint, String text, int maxWidth) {
        final int zhWidth = (int) paint.measureText("汉");  // 单个汉字宽度
        {
            int count = (int) Math.floor(maxWidth / zhWidth);
            TxtLine.adjust = (maxWidth - count * zhWidth) / 2f;
        }
        final int reserveWidth = 0; // 预留宽度
        int lineWidth = 0; // 当前行的宽度
        int restWidth = maxWidth - reserveWidth; //当前行可用宽度
        char[] chs = text.toCharArray();
        int chIndex = 0;
        int chWidth = 0;
        ArrayList<String> lineWords = new ArrayList<>();
        ArrayList<TxtLine> lines = new ArrayList<>();

        while (chIndex < chs.length) {
            char ch = chs[chIndex];

            if (ch < 256) { //英文，单独计算英文的宽度
                chWidth = (int) paint.measureText("" + ch);
            } else {
                chWidth = zhWidth;
            }

            if (restWidth >= chWidth) {  // 当前行可以放下
                restWidth -= chWidth;
                lineWords.add("" + ch);
                lineWidth += chWidth;
            } else { //当前行无法放下
                restWidth = maxWidth - reserveWidth;
                if (isSymbol(ch)) { // 是标点，就将当前行最后一个字以及标点放入下一行，且将下一行重新计算字间距
                    String lastWord = lineWords.remove(lineWords.size() - 1);
                    lines.add(new TxtLine(lineWords, paint.measureText(lastWord)));
                    lineWords = new ArrayList<>();
                    lineWords.add(lastWord);
                    lineWords.add("" + ch);
                    lineWidth = (int) paint.measureText(lastWord) + zhWidth;
                    restWidth -= lineWidth;
                } else {
                    lines.add(new TxtLine(lineWords, 0));
                    lineWords = new ArrayList<>();
                    lineWords.add("" + ch);
                    restWidth -= chWidth;
                    lineWidth = chWidth;
                }
            }

            chIndex++;
        }

        // 判定是否仍有遗留
        if (lineWords.size() > 0) {
            lines.add(new TxtLine(lineWords, 0));
        }

        if (lines.size() > 0) {
            lines.get(lines.size() - 1).setEnd(true);
        }

//        for (TxtLine line: lines) {
//            System.out.print(line);
//        }

        return lines.toArray(new TxtLine[0]);
    }

    /**
     * @return: 将章节内容转换为页对象
     * by zhangjian 2023.9.6
     */
    private List<TxtPage> loadPages(TxtChapter chapter, ArrayList<String> texts) {
        //生成的页面
        List<TxtPage> pages = new ArrayList<>();
        //使用流的方式加载
        ArrayList<TxtLine> allLines = new ArrayList<>();
        final int maxHeight = mVisibleHeight - mTextPara;
        // Log.e("loadPages", "maxHeight --->: " + maxHeight);
        final float textHeight = mTextPaint.getTextSize();
        final float titleHeight = mTitlePaint.getTextSize();
        int rHeight = maxHeight;
        int titleLinesCount = 0;

        try {
            if (true) { // 显示标题
                TxtLine[] lines = cutText(mTitlePaint, chapter.getTitle(), mVisibleWidth);
                allLines.addAll(Arrays.asList(lines));
                titleLinesCount = lines.length;
            }

            for (String text : texts) {
                text = text.replaceAll("\\s", "");
                if (!"".equals(text)) {
                    text = StringUtils.halfToFull("  " + text);
//                    text = "　　" + text;
                    TxtLine[] lines = cutText(mTextPaint, text, mVisibleWidth);
                    allLines.addAll(Arrays.asList(lines));
                }
            }

            List<TxtLine> pageLiens = new ArrayList<>();
            TxtLine line = null;
            int index = 0;
            while (index < allLines.size()) {
                line = allLines.get(index);
                pageLiens.add(line);

                if (index < titleLinesCount) {
                    rHeight -= titleHeight;
                    rHeight -= mTitlePara; //title 的顶部间距
                } else {
                    rHeight -= textHeight;
                }

                if (rHeight <= textHeight + mTextInterval) { //一页已经填充满了，创建 TextPage
                    TxtPage page = new TxtPage();
                    page.position = pages.size();
                    page.title = chapter.getTitle();
                    page.lines.addAll(pageLiens);
                    page.titleLines = titleLinesCount;
                    pages.add(page);
                    // 重置Lines
                    pageLiens.clear();
                    rHeight = maxHeight;
                    titleLinesCount = 0;
                } else {
                    if (index < titleLinesCount) {
                        rHeight -= mTitleInterval;
                    } else {
                        rHeight -= mTextInterval;
                    }

                    if (line.isEnd()) {
                        if (index < titleLinesCount) {
                            rHeight -= mTitlePara - mTitleInterval;
                        } else {
                            rHeight -= mTextPara - mTextInterval;
                        }
                    }
                }

                index++;
            }

            if (pageLiens.size() > 0) {
                TxtPage page = new TxtPage();
                page.position = pages.size();
                page.title = chapter.getTitle();
                page.titleLines = titleLinesCount;
                page.lines.addAll(pageLiens);
                pages.add(page);
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
        } finally {

        }


        return pages;
    }

    /**
     * @return:获取初始显示的页面
     */
    private TxtPage getCurPage(int pos) {
        if (mPageChangeListener != null) {
            mPageChangeListener.onPageChange(pos);
            //第一次加载的时候时候查询权限，发送广播通知权限
            sendsBroadcast();
        }
        if (mCurPageList != null && pos < mCurPageList.size())
            return mCurPageList.get(pos);
        return null;
    }

    /**
     * @return:获取上一个页面
     */
    private TxtPage getPrevPage() {
        int pos = mCurPage.position - 1;
        if (pos < 0) {
            return null;
        }
        if (mPageChangeListener != null) {
            mPageChangeListener.onPageChange(pos);
        }
        return mCurPageList.get(pos);
    }

    /**
     * @return:获取下一的页面
     */
    private TxtPage getNextPage() {
        int pos = mCurPage.position + 1;
        if (pos >= mCurPageList.size()) {
            return null;
        }
        if (mPageChangeListener != null) {
            mPageChangeListener.onPageChange(pos);
        }
        return mCurPageList.get(pos);
    }

    /**
     * @return:获取上一个章节的最后一页
     */
    private TxtPage getPrevLastPage() {
        int pos = mCurPageList.size() - 1;

        if (mPageChangeListener != null) {
            mPageChangeListener.onPageChange(pos);
        }

        return mCurPageList.get(pos);
    }

    /**
     * 根据当前状态，决定是否能够翻页
     *
     * @return
     */
    private boolean canTurnPage() {

        if (!isChapterListPrepare) {
            return false;
        }

        if (mStatus == STATUS_PARSE_ERROR
                || mStatus == STATUS_PARING) {
            return false;
        } else if (mStatus == STATUS_ERROR) {
            mStatus = STATUS_LOADING;
        }
        return true;
    }

    public void setUserIsVip(boolean userIsVip) {
        this.userIsVip = userIsVip;
    }

    /*****************************************interface*****************************************/

    public interface OnPageChangeListener {
        /**
         * 作用：章节切换的时候进行回调
         *
         * @param pos:切换章节的序号
         */
        void onChapterChange(int pos);

        /**
         * 作用：请求加载章节内容
         *
         * @param requestChapters:需要下载的章节列表
         */
        void requestChapters(List<TxtChapter> requestChapters);

        /**
         * 作用：章节目录加载完成时候回调
         *
         * @param chapters：返回章节目录
         */
        void onCategoryFinish(List<TxtChapter> chapters);

        /**
         * 作用：章节页码数量改变之后的回调。==> 字体大小的调整，或者是否关闭虚拟按钮功能都会改变页面的数量。
         *
         * @param count:页面的数量
         */
        void onPageCountChange(int count);

        /**
         * 作用：当页面改变的时候回调
         *
         * @param pos:当前的页面的序号
         */
        void onPageChange(int pos);
    }
}